﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Reflection;
using Ping.Core;
using Ping.Server.Jobs;
using log4net;

namespace Ping.Server
{
	/// <summary>
	/// A scheduler that assigns jobs to requests.
	/// </summary>
	public sealed class JobScheduler
	{
		private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		private readonly Dictionary<Type, Job> _jobs;

		public JobScheduler(IServer server)
		{
			_jobs = new Dictionary<Type, Job>();
			_jobs[typeof (DnsRequest)] = new DnsJob();
			_jobs[typeof (PingRequest)] = new PingJob();
			_jobs[typeof (TracerouteRequest)] = new TracerouteJob();
			_jobs[typeof (GeoRequest)] = new GeoJob(new GeoCache());
			_jobs[typeof(StatusRequest)] = new StatusJob(server);
		}

		/// <summary>
		/// Returns a job that is suitable to handle the given request.
		/// The job must still be performed by the caller.
		/// </summary>
		/// <remarks>
		/// This method is safe to be called from multiple threads.
		/// </remarks>
		/// <param name="request"></param>
		/// <returns></returns>
		public Job GetJob(Request request)
		{
			if (request == null)
				throw new ArgumentNullException();

			Job job;
			if (!_jobs.TryGetValue(request.GetType(), out job))
				throw new ArgumentException(string.Format("Unknwon request type: {0}", request.GetType()));

			return job;
		}
	}
}